import apiCommon from '@/apis/api-common.js';
import fabricAPI from '@/apis/fabric';
import xMinerAPI from '@/apis/xMiner';
import xTagAPI from '@/apis/xTag';
import xVueAPI from '@/apis/xVue';
import Cache from '@/classes/Cache.class.js';
import { getLowCodeExpVal, isExpression } from '@/components/common/low-code/low-code-util.js';
import { sleep, $message } from '@/utils/util.js';

/**
 * 往数据里填充指定的属性，用来生成统一格式的option项
 * @param {*} data 数据
 * @param {string} label 数据中要展示成option 中label的 字段
 * @param {string} value 数据中要做为option 中value的 字段
 */
function addProperty(data = [], label = '', value = '') {
  const list = [];
  if (data === null) {
    return list;
  }
  data.forEach(item => {
    if (item[value]) {
      item.option_label = item[label] || item[value];
      item.option_value = item[value];
      list.push(item);
    }
  });
  return list;
}

const transformSiteId2Code = (list = [], id = '', code = '') => {
  if (id && code) {
    list?.forEach(node => {
      node[id] = node[code] || node[id];
    });
  }
};
const transformDirectoryPageId2Code = (list = [], directory = { id: '', code: '' }, page = { id: '', code: '' }) => {
  const directoryList = list?.data?.[0]?.children || [];
  if (directory.id && directory.code) {
    transformSiteId2Code(directoryList, directory.id, directory.code);
  }
  if (page.id && page.code) {
    directoryList.forEach(item => {
      const pageList = item?.children || [];
      transformSiteId2Code(pageList, page.id, page.code);
    });
  }
};

export default {

  // staticData获取数据源列表
  getDataSourceListstaticData() {
    const list = [{ name: 'staticData_API', code: 'staticData' }];
    return new Promise(resolve => {
      resolve(addProperty(list, 'name', 'code'));
    });
  },

  // xMiner获取数据源列表
  getDataSourceListxMiner() {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataSourceList()
        .then(result => {
          const list = result.data.data.datasourceVo;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // Dac获取数据源列表
  getDataSourceListDac() {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataSourceList('', 'Dac')
        .then(result => {
          const list = result.data.data.datasourceVo;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner公用数据库获取数据源列表(获取公用数据库的数据源)
  getDataSourceListxMinerPublicDatabase() {
    const queryType = 'common';
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataSourceList(queryType)
        .then(result => {
          const list = result.data.data.datasourceVo;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // redis实时获取数据源列表
  getDataSourceListxMinerRedisRealTime() {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataSourceList('', 'Redis')
        .then(result => {
          const list = result.data.data.datasourceVo;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // kafka获取数据源列表
  getDataSourceListkafka() {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataSourceList('', 'kafka')
        .then(result => {
          const list = result.data.data.datasourceVo;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner获取对应数据源的数据表列表
  getDataTableListXMiner(code) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataTableList(code)
        .then(result => {
          const list_ = result.data.data;
          resolve(addProperty(list_, 'remark', 'name'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner公用数据库获取对应数据源的数据表列表
  getDataTableListXMinerPublicDatabase(code) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataTableList(code)
        .then(result => {
          const list = result.data.data;
          resolve(addProperty(list, 'remark', 'name'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // redis实时获取对应数据源的数据表列表
  getDataTableListxMinerRedisRealTime(code) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getDataTableList(code)
        .then(result => {
          const { data } = result.data;
          resolve(addProperty(data, 'remark', 'name'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner获取对应API表的字段列表
  getMappingOptionsxMiner(id) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getMappingOptions(id)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer API查询】权限，请到IAM进行授权',
            });
          }
          const list = result.data.data.apiItemVOList;
          resolve({ list: addProperty(list, 'name', 'code') });
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // Dac获取对应API表的字段列表
  getMappingOptionsDac(id) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getMappingOptions(id)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer API查询】权限，请到IAM进行授权',
            });
          }
          const _list = result.data.data.apiItemVOList;
          resolve({ list: addProperty(_list, 'name', 'code') });
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner公用数据库获取对应API表的字段列表
  getMappingOptionsxMinerPublicDatabase(id) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getMappingOptions(id)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer API查询】权限，请到IAM进行授权',
            });
          }
          const list1 = result.data.data.apiItemVOList;
          resolve({ list: addProperty(list1, 'name', 'code') });
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // redis实时获取对应API表的字段列表
  getMappingOptionsxMinerRedisRealTime(id) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getMappingOptions(id)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer API查询】权限，请到IAM进行授权',
            });
          }
          const list = result.data.data.apiItemVOList;
          const { redisKey } = result.data.data.apiVO;
          resolve({ list: addProperty(list, 'name', 'code'), redisKey });
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // kafka实时获取对应API表的字段列表
  getMappingOptionskafka(id) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getMappingOptions(id)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer API查询】权限，请到IAM进行授权',
            });
          }
          const list = result.data.data.apiItemVOList;
          const { topic } = result.data.data.apiVO;
          resolve({ list: addProperty(list, 'name', 'code'), kafkaTopic: topic });
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner获取对应数据源的apiCode 列表
  getApiListxMiner(datasourceCode) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getAPICodeList(datasourceCode)
        .then(result => {
          const list1 = result.data.data;
          resolve(addProperty(list1, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // Dac获取对应数据源的apiCode 列表
  getApiListDac(datasourceCode) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getAPICodeList(datasourceCode)
        .then(result => {
          const list2 = result.data.data;
          resolve(addProperty(list2, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner公用数据库获取对应数据源的apiCode 列表
  getApiListxMinerPublicDatabase(datasourceCode) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getAPICodeList(datasourceCode, true) // 公用数据库需要传isCommonDatabase为true
        .then(result => {
          const list = result.data.data;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // redis实时获取对应数据源的apiCode 列表
  getApiListxMinerRedisRealTime(datasourceCode) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getAPICodeList(datasourceCode)
        .then(result => {
          const list3 = result.data.data;
          resolve(addProperty(list3, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // kafka实时获取对应数据源的apiCode 列表
  getApiListkafka(datasourceCode) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getAPICodeList(datasourceCode)
        .then(result => {
          const list4 = result.data.data;
          resolve(addProperty(list4, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  getChartDataxMiner(params, subParams = null, allDetail = false, _cacheMs = 0) {
    const getResData = data => {
      if (allDetail) {
        return data;
      } else {
        return data.data || [];
      }
    };

    // 使用缓存
    if (_cacheMs) {
      const cache = Cache.get(params);
      if (cache !== null) {
        return new Promise(r => r(getResData(cache)));
      }
      if (Cache.isCaching(params)) {
        return Cache.getAsync(params).then(_data => getResData(_data));
      }
      Cache.setCaching(params);
    }

    return new Promise((resolve, reject) => {
      xMinerAPI
        .getChartData(params, subParams)
        .then(res => {
          if (res.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【visual-components 数据查询】权限，请到IAM进行授权',
            });
          }
          apiCommon.checkApiResTotal(res, params);
          if (_cacheMs) {
            Cache.set(params, res.data, _cacheMs);
          }
          resolve(getResData(res.data));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  getChartDataDac(params, subParams = null, allDetail = false, cacheMs = 0) {
    const getResData = data => {
      if (allDetail) {
        return data;
      } else {
        return data.data || [];
      }
    };

    // 使用缓存
    if (cacheMs) {
      const cache = Cache.get(params);
      if (cache !== null) {
        return new Promise(r => r(getResData(cache)));
      }
      if (Cache.isCaching(params)) {
        return Cache.getAsync(params).then(data => getResData(data));
      }
      Cache.setCaching(params);
    }

    return new Promise((resolve, reject) => {
      xMinerAPI
        .getChartData(params, subParams)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【visual-components 数据查询】权限，请到IAM进行授权',
            });
          }
          apiCommon.checkApiResTotal(result, params);
          if (cacheMs) {
            Cache.set(params, result.data, cacheMs);
          }
          resolve(getResData(result.data));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  getChartDataxMinerRedisRealTime(params, subParams = null, allDetail = false) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .getChartData(params, subParams)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【visual-components 数据查询】权限，请到IAM进行授权',
            });
          }
          if (allDetail) {
            resolve(result.data);
          } else {
            resolve(result.data.data || []);
          }
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  getChartDataxMinerPublicDatabase(params, subParams = null, allDetail = false) {
    return this.getChartDataxMiner(params, subParams, allDetail);
  },
  getChartDataxMinerPageTable(params, subParams = null) {
    return this.getChartDataxMiner(params, subParams, true);
  },
  getChartDataDacPageTable(params, subParams = null) {
    return this.getChartDataxMiner(params, subParams, true);
  },
  getChartDataxMinerPublicDatabasePageTable(params, subParams = null) {
    return this.getChartDataxMiner(params, subParams, true);
  },

  /** xTag 接口 */
  // xTag获取数据包列表
  getDataSourceListxTag(extraConfig) {
    return new Promise((resolve, reject) => {
      xTagAPI
        .getDataPackageByTenantCode()
        .then(result => {
          const list = result.data.data;

          const optionLabel = (extraConfig && extraConfig.option_label) || 'dataPackageName';
          const optionValue = (extraConfig && extraConfig.option_value) || 'dataPackageCode';

          resolve(addProperty(list, optionLabel, optionValue));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xTag获取对应数据包的apiCode 列表
  getApiListxTag(packageCode) {
    return new Promise((resolve, reject) => {
      xTagAPI
        .getDataTableListByTenantCodeAndPackageCode(packageCode)
        .then(result => {
          const list = result.data.data.tableList;
          resolve(addProperty(list, 'tableAlias', 'tableAlias'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xTag获取对应数据表的字段列表
  getMappingOptionsxTag(tableName, packageCode) {
    return new Promise((resolve, reject) => {
      xTagAPI
        .getMappingOptions(tableName, packageCode)
        .then(result => {
          let list1 = [];
          if (String(result.data.code) === '1') {
            list1 = result.data.data;
            list1.forEach(item => {
              item.type = item.dataType;
            });
          }
          resolve(addProperty(list1, 'columnName', 'columnCode'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xTag获取对应数据表的sql参数
  getSQLParamsOptionsXTag(packageCode, tableName) {
    return new Promise((resolve, reject) => {
      xTagAPI
        .getTableSqlParams(packageCode, tableName)
        .then(result => {
          let list = [];
          if (String(result.data.code) === '1') {
            list = result.data.data;
            list.forEach(item => {
              item.type = item.dataType;
            });
          }
          resolve(addProperty(list, 'columnName', 'columnCode'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },
  getChartDataxTag(params, subParams, allDetail = false) {
    // conditions不能为空数据，否则查询失败
    if (params.conditions && params.conditions.length === 0) {
      params.conditions = [{}];
    }

    const { dataTable: tableName, dataPackage: packageCode } = subParams;
    return new Promise((resolve, reject) => {
      xTagAPI
        .getChartData(params, tableName, packageCode)
        .then(res => {
          apiCommon.checkApiResTotal(res, params);
          if (allDetail) {
            resolve(res.data);
          } else {
            resolve(res.data.data || []);
          }
        })
        .catch(err => {
          reject(err);
        });
    });
  },
  getChartDataxTagPageTable(params, subParams) {
    return this.getChartDataxTag(params, subParams, true);
  },

  /** 数据页签 xtag 宽表 */
  // 获取表格数据
  getTableData(tableName, params, packageCode) {
    return new Promise((resolve, reject) => {
      xTagAPI
        .getTableData(tableName, params, packageCode)
        .then(result => {
          if (String(result.data.code) === '1') {
            resolve({
              data: result.data.data.data,
              total: Number(result.data.data.total),
            });
          } else {
            resolve({
              data: [],
              total: 0,
            });
          }
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  /** page-table组件 异步导出表格数据 */
  asyncExportTableData(params) {
    return new Promise((resolve, reject) => {
      xMinerAPI
        .asyncExportTableData(params)
        .then(result => {
          if (result.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer 根据编排API导出数据】权限，请到IAM进行授权',
            });
          }
          resolve(result.data);
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  /** page-table组件xTag 异步导出表格数据,获取任务id */
  exportAllValueByTableNameAndFields(tableName, params, packageCode) {
    // conditions不能为空数据，否则查询失败
    if (params.conditions && params.conditions.length === 0) {
      params.conditions = [{}];
    }

    return new Promise((resolve, reject) => {
      xTagAPI
        .exportAllValueByTableNameAndFields(tableName, params, packageCode)
        .then(result => {
          resolve(result.data);
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  /** 获取xvue站点页面*/
  getSitePageData() {
    return new Promise((resolve, reject) => {
      xVueAPI
        .getSitePage()
        .then(result => {
          resolve(result.data);
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  /** 获取xvue站点*/
  getSiteListNew() {
    return new Promise((resolve, reject) => {
      xVueAPI
        .getSiteListNew()
        .then(result => {
          transformSiteId2Code(result.data, 'applicationUuid', 'siteCode');
          resolve(result.data);
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  /** 根据站点xvue获取目录和页面*/
  getSiteSingle(params) {
    return new Promise((resolve, reject) => {
      xVueAPI
        .getSiteSingle(params)
        .then(result => {
          transformDirectoryPageId2Code(result, { id: 'uuid', code: 'directoryCode' }, { id: 'uuid', code: 'pageCode' });
          resolve(result.data);
        })
        .catch(err => {
          reject(err);
        });
    });
  },
  getfrequencyTypes() {
    return new Promise((resolve, reject) => {
      xVueAPI
        .getfrequencyTypes()
        .then(result => {
          resolve(result.data);
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  /** 静态数据 */
  getMappingOptionsstaticData(data) {
    const mappingOptions = [];
    let keys = [];
    if (data && data.length) {
      keys = Object.keys(data[0]);
    }
    keys.forEach(key => {
      mappingOptions.push({
        'option_label': key,
        'option_value': key,
      });
    });

    return mappingOptions;
  },

  // xMiner获取数据源列表
  getDataSourceListfabric() {
    return new Promise((resolve, reject) => {
      fabricAPI
        .getDataSourceList()
        .then(result => {
          const _list = result.data.data.datasourceVo;
          resolve(addProperty(_list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // fabric获取api列表
  getApiListfabric(datasourceCode) {
    return new Promise((resolve, reject) => {
      fabricAPI
        .getAPICodeList(datasourceCode)
        .then(result => {
          const list = result.data.data;
          resolve(addProperty(list, 'name', 'code'));
        })
        .catch(err => {
          reject(err);
        });
    });
  },

  // xMiner获取对应API表的字段列表
  getMappingOptionsfabric(apiPathCode) {
    return new Promise((resolve, reject) => {
      fabricAPI
        .getMappingOptions(apiPathCode)
        .then(result => {
          const list = result.data.data.apiItemVOList;
          const params = result.data.data.apiParameterVOList;
          resolve({ list: addProperty(list, 'name', 'code'), params });
        })
        .catch(err => {
          reject(err);
        });
    });
  },
  getChartDatafabric(params, subParams = null, allDetail = false) {
    return new Promise((resolve, reject) => {
      fabricAPI
        .getChartData(params, subParams)
        .then(result => {
          apiCommon.checkApiResTotal(result, params);
          if (allDetail) {
            resolve(result.data);
          } else {
            resolve(result.data.data || []);
          }
        })
        .catch(err => {
          reject(err);
        });
    });
  },
  getChartDatafabricPageTable(params, subParams = null) {
    const _params = params.params || [];
    const codes = _params.map(n => n.code);

    // fabric的分页传参需要放在params里面
    const arr = ['pageIndex', 'pageSize', 'total'];
    arr.forEach(n => {
      if (!codes.includes(n)) {
        _params.push({ code: n, value: params[n] });
      }
    });
    return this.getChartDatafabric(params, subParams, true);
  },

  async getChartDataxVueApi(params, data, allDetail = false) {
    let result;
    if (isExpression(data.dataVal)) {
      // 判断xvue的api是否在请求中，请求中则延迟返回结果
      const rooter = data.dataVal.replace(/^\{\{([^\.]+)\..*\}\}$/, '$1');
      if (rooter && getLowCodeExpVal({ expression: `{{${rooter}.pageApiHasResponsedData}}` }) === false) {
        await sleep(200);
        return this.getChartDataxVueApi(params, data, allDetail);
      }
      result = getLowCodeExpVal({ expression: data.dataVal, vm: params.vm, watchFn: params.watchFn });
    } else {
      result = data.dataVal;
    }

    if (typeof result === 'string') {
      result = [];
    }

    const arr = result.map(n => {
      const item = { ...n };
      Object.entries(params.propertyMapping).map(([field, mapping]) => {
        item[field] = n[mapping];
      });
      return item;
    });

    let res = arr;
    if (allDetail) {
      // 只能模拟结构，保证不报错
      res = {
        data: arr,
        total: arr.length,
      };
    }

    return res;
  },

  getChartDataxVueApiPageTable(params, data) {
    return this.getChartDataxVueApi(params, data, true);
  },
};
